package cn.xuqiudong.rpc.common.util;

import cn.xuqiudong.rpc.common.constants.XqdConstants;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import cn.xuqiudong.rpc.common.model.XqdUrl;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 描述:针对XqdUr 提供一个通用操作
 * @author Vic.xu
 * @date 2022-02-16 10:25
 */
public class XqdUrlUtils {


    /**
     * 把多个path节点转为url列表 去重,去空
     * @param children
     * @return
     */
    public static List<XqdUrl> toUrls(List<String> children){
        if (CollectionUtils.isEmpty(children)){
            return new ArrayList<>();
        }
        List<XqdUrl> urls = children.stream().map(XqdUrlUtils::string2Url).distinct().filter(u->u != null).collect(Collectors.toList());
        return urls;
    }

    /**
     * url转为String
     *  形如：address:port?xx=xxx&yy=yyy  且转义
     * @param url
     * @return
     */
    public static String url2String(XqdUrl url) {
        StringBuilder sb = new StringBuilder();
        sb.append(url.getNode()).append("?");
        sb.append("interfaceName=").append(url.getInterfaceName());
        return encode(sb.toString());

    }

    /**
     * 把string转为url,url2String的反向操作
     * @return
     */
    public static XqdUrl string2Url(String urlString) {
        if (StringUtils.isBlank(urlString)) {
            return null;
        }
        urlString = decode(urlString);
        int index = urlString.indexOf("?");
        String addressStr = urlString.substring(0, index);
        String paramsStr = urlString.substring(index + 1);
        Map<String, String> map = parseParamsStr(paramsStr);
        String address = addressStr.split(":")[0];
        int port = Integer.parseInt(addressStr.split(":")[1]);
        String interfaceName = map.get("interfaceName");
        XqdUrl url = new XqdUrl(address, port, interfaceName);
        return url;

    }

    /**
     * 把url中的非address和端口参数转化为map，方便后续扩展参数
     * @param paramsStr
     * @return
     */
    private static Map<String, String> parseParamsStr(String paramsStr) {
        Map<String, String> map = new HashMap<>();
        for (String params : paramsStr.split("&")) {
            String[] ps = params.split("=");
            map.put(ps[0], ps[1]);
        }
        return map;
    }

    public static String encode(String value) {
        if (StringUtils.isEmpty(value)) {
            return "";
        }
        try {
            return URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static String decode(String value) {
        if (StringUtils.isEmpty(value)) {
            return "";
        }
        try {
            return URLDecoder.decode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 把转化为一个路径地址： 构建父路径 + 当前url转string
     * @return
     */
    public static String toPath(XqdUrl url){
        return findParent(url) + XqdConstants.PATH_SEPARATOR + url2String(url);
    }
    /**
     * 构建一个url的父路径
     * @return
     */
    public static String findParent(XqdUrl url){
        StringBuilder stringBuilder = new StringBuilder();
        //根路径
        stringBuilder.append(XqdConstants.ROOT_PATH).append(XqdConstants.PATH_SEPARATOR);
        //接口全限定名
        stringBuilder.append(url.getInterfaceName()).append(XqdConstants.PATH_SEPARATOR);
        //分类
        stringBuilder.append(XqdConstants.PROVIDERS);
        return stringBuilder.toString();
    }
}
